package com.example.player_plugin;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.easefun.polyvsdk.video.PolyvSeekType;
import com.easefun.polyvsdk.video.PolyvVideoView;
import com.easefun.polyvsdk.video.listener.IPolyvOnCompletionListener2;
import com.easefun.polyvsdk.video.listener.IPolyvOnPreparedListener2;
import com.easefun.polyvsdk.video.listener.IPolyvOnVideoPlayErrorListener2;
import com.easefun.polyvsdk.video.listener.IPolyvOnVideoSizeChangedListener2;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.platform.PlatformView;

public class NativePolyvVideoView implements PlatformView, MethodChannel.MethodCallHandler {
    @NonNull
    private final PolyvVideoView videoView;
    @NonNull
    private final MethodChannel methodChannel;
    @NonNull
    private final Context context;

    private boolean isBuffering = false;

    public NativePolyvVideoView(@NonNull Context context, int viewID, @Nullable Map<String, Object> creationParams, @NonNull BinaryMessenger binaryMessenger) {
        this.context = context;
        methodChannel = new MethodChannel(binaryMessenger, "polyv_video_plugin_" + viewID);
        methodChannel.setMethodCallHandler(this);

        videoView = new PolyvVideoView(context);
        videoView.setSeekType(PolyvSeekType.SEEKTYPE_ACCURATE);
        videoView.setAutoPlay(false);
//        videoView.setMaxCacheDuration(1);
        videoView.setOnPreparedListener(() -> {
            HashMap<String, Boolean> map = new HashMap<String, Boolean>() {
                {
                    put("initialized", true);
                }
            };
            methodChannel.invokeMethod("initialized", map);
        });
        videoView.setOnCompletionListener(() -> {
            if (videoView.isExceptionCompleted()) return;
            methodChannel.invokeMethod("completed", null);
        });
        videoView.setOnVideoSizeChangedListener((width, height, i2, i3) -> {
            HashMap<String, Integer> map = new HashMap<String, Integer>() {
                {
                    put("width", width);
                    put("height", height);
                }
            };
            methodChannel.invokeMethod("videoSize", map);
        });
        videoView.setOnBufferingUpdateListener(i -> {
            HashMap<String, Object> map = new HashMap<String, Object>() {
                {
                    put("bufferPercentage", i);
                    put("isBuffering", isBuffering);
                }
            };
            methodChannel.invokeMethod("bufferingUpdate", map);
        });
        videoView.setOnVideoPlayErrorListener((IPolyvOnVideoPlayErrorListener2) i -> {
            Log.d("onVideoPlayError", String.valueOf(i));
            String reason = "";
            if ( i == 20003) {
                reason = "无法连接网络";
            }
            final String finalReason = reason;
            HashMap<String, String> map = new HashMap<String, String>() {
                {
                    put("code", String.valueOf(i));
                    put("reason", finalReason);
                }
            };
            methodChannel.invokeMethod("videoPlayError", map);
            return true;
        });
        videoView.setOnInfoListener((i, i1) -> {
            /// 701 702 定义在IMediaPlayer里
            /// 701 缓冲开始
            /// 702 缓冲结束
            if (i == 701) {
                isBuffering = true;
            }
            if (i == 702) {
                isBuffering = false;
            }
            return false;
        });
    }

    @Nullable
    @Override
    public View getView() {
        return this.videoView;
    }

    @Override
    public void onFlutterViewAttached(@NonNull View flutterView) {
        PlatformView.super.onFlutterViewAttached(flutterView);
    }

    @Override
    public void onFlutterViewDetached() {
        PlatformView.super.onFlutterViewDetached();
    }

    @Override
    public void dispose() {
        methodChannel.setMethodCallHandler(null);
        videoView.setOnGetCurrentPositionListener(null);
        videoView.setOnPreparedListener((IPolyvOnPreparedListener2) null);
        videoView.setOnCompletionListener((IPolyvOnCompletionListener2) null);
        videoView.setOnVideoSizeChangedListener((IPolyvOnVideoSizeChangedListener2) null);
        videoView.setOnVideoPlayErrorListener((IPolyvOnVideoPlayErrorListener2) null);
        videoView.release();
    }

    @Override
    public void onInputConnectionLocked() {
        PlatformView.super.onInputConnectionLocked();
    }

    @Override
    public void onInputConnectionUnlocked() {
        PlatformView.super.onInputConnectionUnlocked();
    }

    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
        switch (call.method) {
            case "setVid":
                String vid = call.argument("vid");
                videoView.setVid(Objects.requireNonNull(vid));
                result.success(null);
                break;
            case "setVideoURI":
                Uri uri = Uri.parse(call.argument("url"));
                videoView.setVideoURI(uri);
                result.success(null);
                break;
            case "setVideoPath":
                String path = call.argument("path");
                videoView.setVideoPath(Objects.requireNonNull(path));
                result.success(null);
                break;
            case "enableLoop":
                Boolean loop = call.argument("loop");
                videoView.setLooping(Boolean.TRUE.equals(loop));
                result.success(null);
                break;
            case "play":
                videoView.start();
                result.success(null);
                break;
            case "pause":
                videoView.pause();
                result.success(null);
                break;
            case "isPlaying":
                boolean isPlaying = videoView.isPlaying();
                result.success(isPlaying);
                break;
            case "isBuffering":
                result.success(isBuffering);
                break;
            case "duration":
                int millis = videoView.getDuration();
                result.success(millis);
                break;
            case "currentPosition":
                int currentPosition = videoView.getCurrentPosition();
                result.success(currentPosition);
                break;
            case "seekTo":
                int position = Objects.requireNonNull(call.argument("progress"));
                videoView.seekTo(position);
                result.success(null);
                break;
            case "bufferPercentage":
                int percent = videoView.getBufferPercentage();
                result.success(percent);
                break;
            case "brightness":
                int brightness = videoView.getBrightness();
                result.success(brightness);
                break;
            case "volume":
                int volume = videoView.getVolume();
                result.success(volume);
                break;
            case "setBrightness":
                int brightness1 = (int) Objects.requireNonNull(call.argument("brightness"));
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (!Settings.System.canWrite(context)) {
                        Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
                        intent.setData(Uri.parse("package:" + context.getPackageName()));
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        context.startActivity(intent);
                    } else {
                        // 申请权限后做的操作
                        videoView.setBrightness(brightness1);
                    }
                } else {
                    videoView.setBrightness(brightness1);
                }
                break;
            case "setVolume":
                int volume1 = Objects.requireNonNull(call.argument("volume"));
                videoView.setVolume(volume1);
                break;
            case "playbackSpeed":
                double speed = videoView.getSpeed();
                result.success(speed);
                break;
            case "setPlaybackSpeed":
                double needSetSpeed = Objects.requireNonNull(call.argument("speed"));
                videoView.setSpeed((float) needSetSpeed);
                result.success(null);
                break;
            default:
                result.notImplemented();
                break;
        }
    }
}
